پشتیبان گیری و بازیابی باgoogle drive (backup and restore) ...
در این آموزش به روش پشتیبان گیری از برنامه بر روی google drive می پردازیم
همچنین یک نمونه برا ی پشتیبان گیری و بازیابی فایل پشتیبان که در این مثال یک دیتابیس sqlite خواهد بود می آورم.
این مقاله شامل موارد زیر است که مراحل backup و restore از گوگل درایو است را شامل می شود و در ادامه شرح داده شده است:
-ساخت یک Google Drive Android API
-اضافه کردن نیازمندی ها به manifest
-افزودن کلاس های لازم برای آپلود فایل به گوگل درایو از طریق برنامه
-تهیه فایل بکاپ
-بازیابی یک فایل بکاپ
نیازمندی ها:
-نصب بودن sdk
-افزودن google paly service به پروژه
A) ساخت یک پروژه و افزودن Google Play services
1- یک پروژه ی جدید بسازید
2- google play service را به پروژه اضافه کنید
در اندروید استدیو فایل build.gradle(Module:app) را باز کنید و خط زیر را به dependencies اضافه کنید
compile 'com.google.android.gms:play-services-drive:8.4.0'
یعنی به شکل زیر می شود بعلاوه محتویات قبلی
dependencies {
compile 'com.google.android.gms:play-services-drive:8.4.0'
}
3- خطوط زیر را به manifest اضافه کنید
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
کد SHA1 کد اختصاصی برای اپ شماست در مدت تست می توانید از کد SHA1 دیباگ استفاده کنید اما موقع خروجی گرفتن نهایی باید کد SHA1 مربوط به keystore برنامه را وارد کنید
برای بدست آوردن کد SHA1 دیباگ در اندروید استدیو این آموزش را ببینید: روش بدست آوردن کد SHA1
B) ساخت Google Drive Android API
باید یک Google Drive Android API بسازیم
پس از رفع تحریم مراحل را به ترتیب طبق داکیومنت گوگل انجام دهید
- Open the Credentials page. / روی لینک کلیک کنید
-
Follow these steps if your application needs to submit authorized requests: / پس از ورود به پنل مراحل زیر را انجام دهید
- Click Add credentials > OAuth 2.0 client ID.
- Select Android.
- In the Package name field, enter your Android app's package name. // نام پکیج را می توانید از اولین خط یکی از کلاس ها کپی کنید
- Paste the SHA1 fingerprint into the form where requested.// در پاسخ قبلی روش بدست آوردن آن گفته شده
- Click Create. // (:
Otherwise, follow the steps below, which are for applications that only need to make unauthorized API calls:
- Click Add credentials > API key.
- Select Android key.
- Paste the SHA1 fingerprint into the form where requested.
- Type your Android app's package name into the form where requested.
- Click Create.
شما می توانید تمام داکیومت گوگل را درباره این موضوع در این صفحه دنبال کنید
https://developers.google.com/drive/android/get-started
C)کلاس های لازم برای ایجاد بکاپ ،آپلود به گوگل درایو و بازیابی
برای کلاس ها در فرصت مناسب توضیح می نویسم
گوگل برای آپلود و دانلود از درایو یک پروژه ی خوب دارد می توانید آن پروژه را دنلود و استفاده کنید:
https://github.com/googledrive/android-quickstart
با این حال من بخش کوچکی از آن پروژه را در این مثال استفاده کردم
در پروژه ای که ساختید کلاس های زیر را اضافه کنید :
کلاس BackupBace.java
package your pakage name;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.drive.Drive;
/**
* An abstract activity that handles authorization and connection to the Drive
* services.
*/
public abstract class BackupBaceextends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "BaseDriveActivity";
/**
* DriveId of an existing folder to be used as a parent folder in
* folder operations samples.
*/
public static final String EXISTING_FOLDER_ID = "0B2EEtIjPUdX6MERsWlYxN3J6RU0";
/**
* DriveId of an existing file to be used in file operation samples..
*/
public static final String EXISTING_FILE_ID = "0ByfSjdPVs9MZTHBmMVdSeWxaNTg";
/**
* Extra for account name.
*/
protected static final String EXTRA_ACCOUNT_NAME = "account_name";
/**
* Request code for auto Google Play Services error resolution.
*/
protected static final int REQUEST_CODE_RESOLUTION = 1;
/**
* Next available request code.
*/
protected static final int NEXT_AVAILABLE_REQUEST_CODE = 2;
/**
* Google API client.
*/
private GoogleApiClient mGoogleApiClient;
/**
* Called when activity gets visible. A connection to Drive services need to
* be initiated as soon as the activity is visible. Registers
* {@code ConnectionCallbacks} and {@code OnConnectionFailedListener} on the
* activities itself.
*/
@Override
protected void onResume() {
super.onResume();
}
public void connectDrive(){
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addScope(Drive.SCOPE_APPFOLDER) // required for App Folder sample
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
/**
* Handles resolution callbacks.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_RESOLUTION && resultCode == RESULT_OK) {
mGoogleApiClient.connect();
}
else {
finish();
G.currentActivity.finish();
Intent intent=new Intent(G.currentActivity,ActivityBackupHom.class);
G.currentActivity.startActivity(intent);
Toast.makeText(G.context,G.context.getResources().getString(R.string.connection_faild),Toast.LENGTH_LONG).show();
}
}
/**
* Called when activity gets invisible. Connection to Drive service needs to
* be disconnected as soon as an activity is invisible.
*/
@Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
/**
* Called when {@code mGoogleApiClient} is connected.
*/
@Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "GoogleApiClient connected");
}
/**
* Called when {@code mGoogleApiClient} is disconnected.
*/
@Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
/**
* Called when {@code mGoogleApiClient} is trying to connect but failed.
* Handle {@code result.getResolution()} if there is a resolution is
* available.
*/
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
// show the localized error dialog.
GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
return;
}
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
/**
* Shows a toast message.
*/
public void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
/**
* Getter for the {@code GoogleApiClient}.
*/
public GoogleApiClient getGoogleApiClient() {
connectDrive();
return mGoogleApiClient;
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
}
کلاس ActivityBackupHom.java
package your pakage;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi;
import com.google.android.gms.drive.MetadataChangeSet;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
public class ActivityBackupHom extends BackupBase {
public static String TAG="LOG";
static final String MIMQLITE = "application/x-sqlite3";// برای sqlite
Button btnBackupRemote,btnRetriveRemote;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
btnBackupRemote=(Button)findViewById(R.id.btnBackupRemote);
btnRetriveRemote=(Button)findViewById(R.id.btnRetriveRemote);
btnBackupRemote.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
backUpToDriveTask mTask = new backUpToDriveTask();
mTask.mTitle = "Thread";
mTask.file = G.file;
mTask.mime = MIMQLITE;
mTask.execute();
}
});
btnRetriveRemote.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(G.currentActivity,RetrieveBackup.class);
G.currentActivity.startActivity(intent);
}
});
}
//**************************************
class backUpToDriveTask extends AsyncTask<String, String, String> {
public String mTitle;
public String mMessage;
public File file;
public String mime;
public int dprogress=0;
ProgressDialog mProgressDialog;
@Override
protected void onPreExecute() {
mProgressDialog = new ProgressDialog(G.currentActivity);
mProgressDialog.setMessage("Please white....");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
super.onPreExecute();
}
@Override
protected String doInBackground(String... progress) {
Thread.currentThread().setName(mTitle);
Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(
new ResultCallback<DriveApi.DriveContentsResult>() {
@Override
public void onResult(DriveApi.DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.i(TAG, "Failed to create new contents.");
return;
}
Log.i(TAG, "Connection successful, creating new contents...");
// Otherwise, we can write our data to the new contents.
// Get an output stream for the contents.
OutputStream outputStream = result.getDriveContents().getOutputStream();
FileInputStream fis;
try {
fis = new FileInputStream(file.getPath());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf)))
baos.write(buf, 0, n);
byte[] photoBytes = baos.toByteArray();
outputStream.write(photoBytes);
outputStream.close();
outputStream = null;
fis.close();
fis = null;
} catch (FileNotFoundException e) {
Log.w(TAG, "FileNotFoundException: " + e.getMessage());
} catch (IOException e1) {
Log.w(TAG, "Unable to write file contents." + e1.getMessage());
}
String title = ""+ MC.getCurrentDate().replace("-","")+file.getName();
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType(mime).setTitle(title).build();
Log.i(TAG, "Creating new photo on Drive (" + title + ")");
Drive.DriveApi.getRootFolder(getGoogleApiClient()).createFile(getGoogleApiClient(),
metadataChangeSet,
result.getDriveContents());
}
});
publishProgress(""+dprogress);
return null;
}
@Override
protected void onProgressUpdate(String... progress) {
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
super.onProgressUpdate(progress);
}
@Override
protected void onPostExecute(String result) {
mProgressDialog.dismiss();
super.onPostExecute(result);
}
}
@Override
protected void onResume() {
super.onResume();
G.currentActivity=this;
}
}
کلاس RetrieveBackup.java
package your pakage;
import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.widget.ProgressBar;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi.DriveContentsResult;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveFile.DownloadProgressListener;
import com.google.android.gms.drive.DriveId;
import com.google.android.gms.drive.OpenFileActivityBuilder;
import java.io.File;
import java.io.InputStream;
/**
* An activity to illustrate how to open contents and listen
* the download progress if the file is not already sync'ed.
*/
public class RetrieveBackup extends BackupBase {
private static final String TAG = "LOG";
/**
* Request code to handle the result from file opening activity.
*/
private static final int REQUEST_CODE_OPENER = 1;
/**
* Progress bar to show the current download progress of the file.
*/
private ProgressBar mProgressBar;
/**
* File that is selected with the open file activity.
*/
private DriveId mSelectedFileDriveId;
@Override
protected void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.activity_progress);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mProgressBar.setMax(100);
}
@Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
// If there is a selected file, open its contents.
if (mSelectedFileDriveId != null) {
open();
return;
}
// Let the user pick an mp4 or a jpeg file if there are
// no files selected by the user.
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
// .setMimeType(new String[]{ "video/mp4", "image/jpeg" })
.setMimeType(new String[]{ ActivityBackupHom.MIMQLITE, ActivityBackupHom.MIMQLITE })
.build(getGoogleApiClient());
try {
startIntentSenderForResult(intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.w(TAG, "Unable to send intent", e);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_OPENER && resultCode == RESULT_OK) {
mSelectedFileDriveId = (DriveId) data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
private void open() {
// Reset progress dialog back to zero as we're
// initiating an opening request.
mProgressBar.setProgress(0);
DownloadProgressListener listener = new DownloadProgressListener() {
@Override
public void onProgress(long bytesDownloaded, long bytesExpected) {
// Update progress dialog with the latest progress.
int progress = (int)(bytesDownloaded*100/bytesExpected);
Log.d(TAG, String.format("Loading progress: %d percent", progress));
mProgressBar.setProgress(progress);
}
};
DriveFile driveFile = mSelectedFileDriveId.asDriveFile();
driveFile.open(getGoogleApiClient(), DriveFile.MODE_READ_ONLY, listener)
.setResultCallback(driveContentsCallback);
mSelectedFileDriveId = null;
}
private ResultCallback<DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveContentsResult>() {
@Override
public void onResult(DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while opening the file contents");
return;
}
InputStream inputStream;
try {
DriveContents driveContents = result.getDriveContents();
inputStream = driveContents.getInputStream();
HelperIO.copyFile(inputStream, G.DIR_DATABASE + "/rest_database.sqlite");
}
catch (Exception e) {
e.printStackTrace();
}
showMessage("File contents opened");
File file = new File(G.DIR_DATABASE + "/rest_database.sqlite");
boolean isExist = G.file.exists();
boolean restored = file.exists();
if(restored){
if(isExist){
G.file.delete();
}
File from = new File(G.DIR_DATABASE,"rest_database.sqlite");
File to = new File(G.DIR_DATABASE,"database.sqlite");
if(from.exists())
from.renameTo(to);
}
}
};
//
@Override
protected void onResume() {
super.onResume();
connectDrive();
}
}
package ??????;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
public class HelperIO {
public static void closeStream(InputStream stream) {
try {
stream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void closeStream(OutputStream stream) {
try {
stream.flush();
stream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void closeChannel(FileChannel channel) {
try {
channel.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void copyFile(String inputFilename, String outputFilename) {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new FileInputStream(inputFilename);
outputStream = new FileOutputStream(outputFilename);
copyFile(inputStream, outputStream);
}
catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
closeStream(inputStream);
closeStream(outputStream);
}
}
public static void copyFile(String inputFilename, OutputStream outputStream) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(inputFilename);
copyFile(inputStream, outputStream);
}
catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
closeStream(inputStream);
closeStream(outputStream);
}
}
public static void copyFile(InputStream inputStream, String outputFilename) {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(outputFilename);
copyFile(inputStream, outputStream);
}
catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
closeStream(inputStream);
closeStream(outputStream);
}
}
public static void copyFile(InputStream inputStream, OutputStream outputStream) {
byte[] buffer = new byte[8 * 1024];
int lenRead = 0;
try {
while ((lenRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, lenRead);
}
}
catch (IOException e) {
e.printStackTrace();
} finally {
closeStream(inputStream);
closeStream(outputStream);
}
}
}
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .